package hamelin

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"path"
	"runtime"
	"strings"
)

const SEP = `--->> S ---->> E ---->> P ---->>`

type Loger struct {
	Name  string
	_tree *TreeMap
}

func NewLoger(roots ...string) (loger *Loger, err error) {
	loger = new(Loger)
	name := "hamelin.logs"
	root := path.Join("/var/log", name)
	if runtime.GOOS == "windows" {
		h, _ := os.UserHomeDir()
		root = path.Join(h, "Desktop", name)
	}
	if len(roots) > 1 {
		name = roots[0]
		root = path.Join(roots[1], name)
	} else if len(roots) > 0 {
		root = path.Join(roots[0], name)
	}
	loger.Name = name
	if !Exists(root) {
		os.Mkdir(root, os.ModePerm)
	}
	if loger._tree, err = NewTree(root); err != nil {
		log.Fatal(err)
	}
	return
}

func (loger *Loger) BaseRecord(args ...interface{}) {
	subTree := true
	nowtree := loger._tree
	strargs := []string{}
	logname := "base"
	contents := []string{}
	for _, arg := range args {

		xType := fmt.Sprintf("%T", arg)
		// fmt.Println("t:", xType)
		if xType == "string" {
			if subTree {
				strargs = append(strargs, arg.(string))
				continue
			}
		} else if strings.Contains(xType, "map[string]") {
			if buf, err := json.Marshal(&arg); err == nil {
				contents = append(contents, string(buf))
				continue
			} else {
				log.Println("json err :", arg)
			}
		} else if xType == "[]uint8" {
			contents = append(contents, string(arg.([]byte)))
			continue
		} else if xType == "[]byte" {
			contents = append(contents, string(arg.([]byte)))
			continue
		} else if strings.Contains(xType, "[]") {
			tryTest := arg.([]interface{})[0]
			tryType := fmt.Sprintf("%T", tryTest)
			if strings.Contains(tryType, "map") || tryType == "string" {
				if buf, err := json.Marshal(&arg); err == nil {
					contents = append(contents, string(buf))
					continue
				} else {
					log.Println("json err :", arg)
				}
			} else {
				log.Println("i do not know this :", tryTest)
			}

		} else {
			subTree = false
		}
		contents = append(contents, fmt.Sprintf("%v", arg))

	}
	cc := len(strargs)
	if cc > 0 {
		for c, v := range strargs {
			if c < cc-1 {
				nowtree = nowtree.AddTree(v)
			} else if c == cc-1 {
				logname = v
			}
		}
	}
	if len(contents) == 0 && len(strargs) > 1 {
		nowtree = nowtree.Delete()
		logname = strargs[len(strargs)-2]
		contents = []string{strargs[len(strargs)-1]}
	}
	nowtree.AddNode(logname, strings.Join(contents, SEP))
}

func (loger *Loger) TLog(indexName, timeStr, name string, content interface{}) {
	loger.BaseRecord(indexName, timeStr, name, content)
}
